﻿using HalconDotNet;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls.Primitives;
using System.Windows.Forms;

namespace C_与Halcon联合编程实现车牌识别
{
    public partial class Form1 : Form
    {
        // 声明全局变量
        private HWindow _hWindow; //显示窗体的引用
        private HFramegrabber _framegrabber; //相机采集器
        private bool _isGrabbing = false; //是否继续采集
        private Thread _grabThread; //声明一个实时采集图像的线程
        HImage image = null;
        HRegion region = new HRegion();

        // 初始化相机
        private void InitializeCamera()
        {
            try
            {
                // 打开相机（参数需根据相机类型调整）
                _framegrabber = new HFramegrabber("GigEVision2", 0, 0, 0, 0, 0, 0, "default",
                                                  -1, "default", -1, "false", "default",
                                                  "default", 0, -1);

                // 获取 HSmartWindowControl 的 Halcon 窗口句柄
                _hWindow = hwcCar.HalconWindow;
            }
            catch (HalconException ex)
            {
                //MessageBox.Show($"相机初始化失败: {ex.Message}");
            }
        }

        // 开始实时采集
        private void StartGrabbing()
        {
            if (_framegrabber == null) InitializeCamera();

            _isGrabbing = true;
            //定义线程，在线程方法进行图像循环采集
            _grabThread = new Thread(GrabLoop);
            _grabThread.IsBackground = true;
            _grabThread.Start();
        }

        // 采集循环（在独立线程中运行）
        private void GrabLoop()
        {
            while (_isGrabbing)
            {
                try
                {
                    // 抓取图像
                    image = _framegrabber.GrabImageAsync(-1);

                    // 在 Halcon 窗口中显示图像
                    _hWindow.DispObj(image);
                    HTuple width;
                    HTuple height;
                    HOperatorSet.GetImageSize(image, out width, out height);
                    HOperatorSet.SetPart(hwcCar.HalconWindow, 0, 0, height - 1, width - 1);
                    image.Dispose();
                }
                catch (HalconException ex)
                {
                    // 处理异常（如相机断开）
                    if (ex.GetErrorCode() == 5302) // 采集超时
                        Thread.Sleep(1000);
                    else
                        break;
                }
            }
        }

        // 停止采集
        private void StopGrabbing()
        {
            _isGrabbing = false;
            _grabThread?.Join(); // 等待线程结束
            _framegrabber?.Dispose();
            _framegrabber = null;
        }
        public Form1()
        {
            InitializeComponent();
            //hwcCar.MouseWheel += (sender, e) =>
            //{
            //    hwcCar.(sender, e);
            //};
            InitializeCamera();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //OpenFileDialog openFileDialog = new OpenFileDialog();
            //openFileDialog.Filter = "所有图片|*.jpg";
            //openFileDialog.Title = "加载图片";
            //openFileDialog.RestoreDirectory = true;
            //if (openFileDialog.ShowDialog() == DialogResult.OK)
            //{
            //    image = new HImage(openFileDialog.FileName);
            //    HTuple width;
            //    HTuple height;
            //    HOperatorSet.GetImageSize(image, out width, out height);
            //    HOperatorSet.SetPart(hwcCar.HalconWindow, 0, 0, height - 1, width - 1);
            //    hwcCar.HalconWindow.DispObj(image);
            //}
            StartGrabbing();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //写了一天的代码
            Console.WriteLine();
            //以图片中点为旋转点进行旋转
            HOperatorSet.TextLineOrientation(image,image, 50, -0.872665, 0.872665,out HTuple angle);
            double phi = angle;
            HImage rotateimage= image.RotateImage(-phi / 3.14 * 180, "constant");
            //提升对比度
            HImage ImageEmphasize = rotateimage.Emphasize(7,7,1);
            //中值滤波
            HImage ImageMedian = rotateimage.MedianImage("circle", 5, "mirrored");
            //转换为三通道
            HImage redImage= ImageEmphasize.Decompose3(out HImage greenImage,out HImage blueImage);
            //转换为HSV
            HImage hImage= redImage.TransFromRgb(greenImage,blueImage,out HImage sImage, out HImage vImage,"hsv");
            //自动全局阈值分割
             HRegion Region= sImage.BinaryThreshold("max_separability","light",out HTuple UsedThreshold);
            //开运算
            HRegion RegionOpening= Region.OpeningCircle(2.0);
            //区域连通
            HRegion ConnectedRegions= RegionOpening.Connection();
            //特征提取
            HRegion SelectedRegions = ConnectedRegions.SelectShape("area","and",32000,350000).SelectShape("rectangularity", "and",0.4,1).SelectShape("row", "and",0,2780);
            //膨胀
            HRegion RegionDilation1= SelectedRegions.DilationCircle(8.0);
            //填充
            HRegion RegionFillUp1= RegionDilation1.FillUp();
            //合并
            HRegion RegionUnion1= RegionFillUp1.Union1();
            //区域连通
            HRegion ConnectedRegions2 = RegionUnion1.Connection();
            //转换为矩形
            HRegion RegionTrans2= ConnectedRegions2.ShapeTrans("rectangle2");
            //通过矩阵数量判断是否存在车牌区域
            int Number=RegionTrans2.CountObj();
            //生成一个空对象
            HOperatorSet.GenEmptyObj(out HObject ROI);
            for (int i = 1; i <= Number; i++) 
            {
                HRegion ObjectSelected=RegionTrans2.SelectObj(i);
                // 长半轴
                double Value1 = ObjectSelected.RegionFeatures("rect2_len1");
                // 短半轴
                double Value2 = ObjectSelected.RegionFeatures("rect2_len2");
                double a=Value1/Value2;
                if(a > 2.8 && a < 4.3)
                {
                    ROI= ROI.ConcatObj(ObjectSelected);
                }
            }
            int Number1=ROI.CountObj();
            if (Number1==1)
            {
                //腐蚀
                HRegion hRegion=new HRegion(ROI);
                HRegion RegionErosion = hRegion.ErosionRectangle1(80,80);
                //裁剪
                HImage ImageReduced = ImageMedian.ReduceDomain(RegionErosion);
                //自动全局阈值分割
               HRegion Region1= ImageReduced.BinaryThreshold("max_separability","light", out HTuple UsedThreshold1);
                //区域连通
                HRegion ConnectedRegions1=Region1.Connection();
                //特征提取
                HRegion SelectedRegions1 = ConnectedRegions1.SelectShape("contlength","and",105,150000).SelectShape("area","and",500,100000);
                //膨胀
               HRegion RegionDilation = SelectedRegions1.DilationCircle(8.0);
                //合并
                HRegion RegionUnion=RegionDilation.Union1();
                //连通区域
                HRegion ConnectedRegions3= RegionUnion.Connection();
                //交集
                HRegion RegionIntersection= ConnectedRegions3.Intersection(SelectedRegions1);
                //排序
                HRegion SortedRegions=RegionIntersection.SortRegion("character", "true", "row");
                //加载omc文件
                HOCRMlp mlp=new HOCRMlp();
                mlp.ReadOcrClassMlp("charact.omc");
                //识别信息
               HTuple Class= mlp.DoOcrMultiClassMlp(SortedRegions, ImageReduced,out HTuple Confidence);
                this.richTextBox1.Text = "";
                for (int i = 0; i < Class.Length; i++)
                {
                    this.richTextBox1.Text += Class.TupleSelect(i);
                }
                HTuple width;
                HTuple height;
                HOperatorSet.GetImageSize(ImageReduced, out width, out height);
                HOperatorSet.SetPart(hwcCar2.HalconWindow, 0, 0, height - 1, width - 1);
                hwcCar2.HalconWindow.ClearWindow();
                hwcCar2.HalconWindow.DispObj(ImageReduced);

            }
            else
            {
                //特征提取
                HRegion hRegion1 =new HRegion(ROI);    
                HRegion ROI2= hRegion1.SelectShape("area", "and", 110000, 340000);
                //腐蚀
                HRegion RegionErosion= ROI2.ErosionRectangle1(80,120);
                //裁剪区域
                HImage ImageReduced=ImageMedian.ReduceDomain(RegionErosion);
                //自动全局阈值分割
                HRegion Region1 = ImageReduced.BinaryThreshold("max_separability", "light", out HTuple UsedThreshold1);
                //连通区域
                HRegion ConnectedRegions1= Region1.Connection();
                //特征提取
                HRegion SelectedRegions1 = ConnectedRegions1.SelectShape("contlength", "and", 105, 150000).SelectShape("area", "and", 600, 100000);
                //膨胀
                HRegion RegionDilation= SelectedRegions1.DilationCircle(8.0);
                //合并
                HRegion RegionUnion= RegionDilation.Union1();
                //连通区域
                HRegion ConnectedRegions3= RegionUnion.Connection();
                //取交集
                HRegion RegionIntersection= ConnectedRegions3.Intersection(SelectedRegions1);
                //排序
                HRegion SortedRegions= RegionIntersection.SortRegion("character", "true", "row");
                //加载omc文件
                HOCRMlp mlp = new HOCRMlp();
                mlp.ReadOcrClassMlp("charact.omc");
                //识别信息
                HTuple Class = mlp.DoOcrMultiClassMlp(SortedRegions, ImageReduced, out HTuple Confidence);

                string[] array = Class.ToSArr();
                string str = "";
                for (int i = 0; i < Class.Length; i++)
                {
                    str += array[i];
                }
                this.richTextBox1.Text = str;
                HTuple width;
                HTuple height;
                HOperatorSet.GetImageSize(ImageReduced, out width, out height);
                HOperatorSet.SetPart(hwcCar2.HalconWindow, 0, 0, height - 1, width - 1);
                hwcCar2.HalconWindow.ClearWindow();
                hwcCar2.HalconWindow.DispObj(ImageReduced);


            }




        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            StopGrabbing();
        }
    }
}
